const LazyLoad = {
	// install
	install(Vue, options) {
		// loading
		let defaultSrc = options.default;
		Vue.directive("lazy", {
			bind(el, binding) {
				LazyLoad.init(el, binding.value, defaultSrc);
			},
			inserted(el) {
				//
				if ("IntersectionObserver" in window) {
					LazyLoad.observe(el);
				} else {
					LazyLoad.listenerScroll(el);
				}
			},
		});
	},
	//
	init(el, val, def) {
		// data-src src
		el.setAttribute("data-src", val);
		// src loading
		el.setAttribute("src", def);
	},
	// IntersectionObserver el
	observe(el) {
		let io = new IntersectionObserver(entries => {
			let realSrc = el.dataset.src;
			if (entries[0].isIntersecting) {
				if (realSrc) {
					el.src = realSrc;
					el.removeAttribute("data-src");
				}
			}
		});
		io.observe(el);
	},
	// scroll
	listenerScroll(el) {
		let handler = LazyLoad.throttle(LazyLoad.load, 300);
		LazyLoad.load(el);
		window.addEventListener("scroll", () => {
			handler(el);
		});
	},
	//
	load(el) {
		let windowHeight = document.documentElement.clientHeight;
		let elTop = el.getBoundingClientRect().top;
		let elBtm = el.getBoundingClientRect().bottom;
		let realSrc = el.dataset.src;
		if (elTop - windowHeight < 0 && elBtm > 0) {
			if (realSrc) {
				el.src = realSrc;
				el.removeAttribute("data-src");
			}
		}
	},
	//
	throttle(fn, delay) {
		let timer;
		let prevTime;
		return function (...args) {
			let currTime = Date.now();
			let context = this;
			if (!prevTime) prevTime = currTime;
			clearTimeout(timer);

			if (currTime - prevTime > delay) {
				prevTime = currTime;
				fn.apply(context, args);
				clearTimeout(timer);
				return;
			}
			timer = setTimeout(function () {
				prevTime = Date.now();
				timer = null;
				fn.apply(context, args);
			}, delay);
		};
	},
};
export default LazyLoad;
